<?php
namespace ZHMVC\B\TOOL;
class ClsWxxcxma{
    
    var $width  = 430;  #@菊花码的宽
    var $line_color  = array('r'=>0,'g'=>0,'b'=>0);  #@菊花码的线颜色默认值
    var $appid = "wxb9c0587c5a3a9d28";
    var $appsecret = "2ed68457413b162793b06c67efb99609";
    // var $imgPath = ROOT_PATH . 'images/qrcode_juhuama/';    #@菊花码存储路径
    // var $imgPath =  'D:/phpStudy/PHPTutorial/WWW/images/qrcode_juhuama/';    #@菊花码存储路径
    var $imgPath =  ZH_PATH.'/upload/';    #@菊花码存储路径
    var $imgurl ='';
    
    var $error = [
        '45029'=>   '生成码个数总和到达最大个数限制',
        '45009'=>   '调用分钟频率受限(目前5000次/分钟，会调整)，如需大量小程序码，建议预生成',
        '41030'=>   '所传page页面不存在，或者小程序没有发布',
    ];
    
    
    function __construct(){
        
        // $wcfg =  $GLOBALS['db']->getRow("SELECT * FROM wxch_config ");
        $wcfg = [
            'appid'=>'wxb9c0587c5a3a9d28',
            'appsecret'=>'2ed68457413b162793b06c67efb99609'
        ];
        
        $this->appid = $wcfg['appid'];
        $this->appsecret = $wcfg['appsecret'];
        // $this->imgurl = "http://".$_SERVER['HTTP_HOST']."/mobile/images/qrcode_juhuama/";
        $this->imgurl = "http://".$_SERVER['HTTP_HOST']."/upload/";
    }
    
    
    #A接口，生成小程序码，可接受path参数较长，生成个数受限【菊花码】
    /*
     一、获取菊花码的方式一 【不可带用户自定义参数】
     适用场景: 适用于需要的码数量较少的业务场景
     接口地址：https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN
     注    意：通过该接口生成的小程序码，永久有效，数量限制见文末说明，请谨慎使用。用户扫描该码进入小程序后，
     将直接进入 path 对应的页面。
     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     传输方式：  POST
     参数        类型    默认值 说明
     path        String          不能为空，最大长度 128 字节 如path="pages/mine/mine/mine?query=1";
     width       Int     430     二维码的宽度
     auto_color  Bool    false   自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调
     line_color  Object  {"r":"0","g":"0","b":"0"}   auto_color 为 false 时生效，使用 rgb 设置颜色 例如
     {"r":"xxx","g":"xxx","b":"xxx"},十进制表示
     is_hyaline  Bool    false   是否需要透明底色， is_hyaline 为true时，生成透明底色的小程序码
     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    /**
     * [getwxaqrcode 获取菊花码方式一 ]
     * @param  [type] $parameter [数组
     *$parameter = array(
     *      'path'=>[string],
     *      'width'=>[int],
     *      'auto_color'=>[bool],
     *      'line_color'=>array('r'=>0,'g'=>0,'b'=>0),
     *      'is_hyaline'=>[bool],
     *);
     *
     *
     * @return [type]       [description]
     */
    public function getwxaqrcode_a($parameter)
    {
        // 存储路径
        $imgPath = $this->imgPath.'A/';
        if (!is_dir($imgPath)) {
            mkdir($imgPath);
        }
        
        if (!is_array($parameter)) {
            return array('status'=>0,'errmsg'=>'传入参数必须是数组');
        }
        if (!isset($parameter['path']) || empty($parameter['path'])) {
            return array('status'=>0,'errmsg'=>'缺少必要参数path');
        }
        if (!isset($parameter['width']) || empty($parameter['width'])) {
            $parameter['width'] = $this->width;
        }
        if (!isset($parameter['auto_color']) || empty($parameter['auto_color'])) {
            $parameter['auto_color'] = false;
        }
        if (!isset($parameter['line_color']) || empty($parameter['line_color']) || !is_array($parameter['line_color'])) {
            $parameter['line_color'] = $this->arrayToObject($this->line_color);
        }
        if (!isset($parameter['is_hyaline']) || empty($parameter['is_hyaline'])) {
            $parameter['is_hyaline'] = false;
        }
        
        
        $path = array(
            'path'=>$parameter['path'],
            'width'=>$parameter['width'],
            'auto_color'=>$parameter['auto_color'],
            'line_color'=>$parameter['line_color'],   #@此参数要的是对象
            'is_hyaline'=>$parameter['is_hyaline'],
        );
        $data = json_encode($path);
        $imgname = md5($data).'.png';  #@图片名称 图片永久有效
        
        if (!is_file($imgPath . $imgname)) { //创建图片
            set_time_limit(0);
            @ini_set('memory_limit', '256M');
            
            
            $access_token = $this->AccessToken();
            
            $url = 'https://api.weixin.qq.com/wxa/getwxacode?access_token='.$access_token;
            // $path="pages/mine/mine/mine?query=1";
            // $data='{"path":"'.$path.'","width":'.$this->width.'}';
            $return = $this->request_post($url,$data);
            
            
            $return_decode = json_decode($return,true);
            if (isset($return_decode['errcode'])) {
                $errcodeMsg = isset($this->error[$return_decode['errcode']])?$this->error[$return_decode['errcode']]:'';
                return array('status'=>0,'errcode'=>$return_decode['errcode'],'errmsg'=>$return_decode['errmsg'],'msg'=>$errcodeMsg);
            }else{
                
                //将生成的小程序码存入相应文件夹下
                file_put_contents($imgPath.$imgname,$return);
                
            }
            
            
        }
        
        // 报错信息
        //{"errcode":47001,"errmsg":"data format error hint: [bApcla09642159]"}
        
        // return array(1,$this->imgurl.'A/'.$imgname);
        return array('status'=>1,'qrcodeurl'=>$this->imgurl.'A/'.$imgname);
    }
    
    
    
    #B接口，生成小程序码，可接受页面参数较短，生成个数不受限【菊花码】。
    /*
     二、获取菊花码的方式二 【可以带用户自定义参数】
     适用场景：适用于需要的码数量极多的业务场景
     接口地址：https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
     注    意：通过该接口生成的小程序码，永久有效，数量暂无限制。用户扫描该码进入小程序后，
     开发者需在对应页面获取的码中 scene 字段的值，再做处理逻辑。
     使用如下代码可以获取到二维码中的 scene 字段的值。
     调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟，
     开发工具模拟时的 scene 的参数值需要进行 urlencode
     参数获取
     // 这是首页的 js
     Page({
     onLoad: function(options) {
     // options 中的 scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
     var scene = decodeURIComponent(options.scene)
     }
     })
     
     
     
     #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@注意
     接收的参数传回PHP一定要用这个去除转义
     stripcslashes() 删除由 addcslashes() 函数添加的反斜杠。
     stripslashes()    删除由 addslashes() 函数添加的反斜杠。
     
     
     特殊符号转义
     urldecode()
     
     
     
     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     传输方式：  POST
     参数        类型          默认值                       说明
     scene       String                                     最大32个可见字符，只支持数字，
     大小写英文以及部分特殊字符：!#$&'()*+,/:;=?@-._~，其它字符请自行编码为合法字符（因不支持%，中文无法使用 urlencode 处理，请使用其他编码方式）
     page        String                                     必须是已经发布的小程序存在的页面（否则报错），
     例如 "pages/index/index" ,根路径前不要填加'/',不能携带参数（参数请放在scene字段里），如果不填写这个字段，默认跳主页面
     width       Int           430                          二维码的宽度
     auto_color  Bool          false                        自动配置线条颜色，如果颜色依然是黑色，
     则说明不建议配置主色调
     line_color  Object        {"r":"0","g":"0","b":"0"}    auto_color 为 false 时生效，使用 rgb 设置颜色
     例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
     is_hyaline  Bool          false                        是否需要透明底色， is_hyaline 为true时，
     生成透明底色的小程序码
     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    
    
    /**
     * [getwxaqrcode 获取菊花码方式一 不带用户自定义参数]
     * @param  [type] $parameter [数组
     *$parameter = array(
     *      'scene'=>[string]/[array],
     *      'page'=>[string],
     *      'width'=>[int],
     *      'auto_color'=>[bool],
     *      'line_color'=>array('r'=>0,'g'=>0,'b'=>0),
     *      'is_hyaline'=>[bool],
     *);
     *
     *
     * @return [type]       [description]
     */
    public function getwxaqrcode_b($parameter,$userid)
    {
        // 存储路径
        $imgPath = $this->imgPath.'B/';
        $imgPath1 = ZH_PATH.'/upload/B/';
        if (!is_dir($imgPath1)) {
            mkdir($imgPath1);
        }
        $imgPath = $imgPath.$userid.'/';
        $imgPath1 = $imgPath1.$userid.'/';
        if (!is_dir($imgPath1)) {
            mkdir($imgPath1);
        }
        if (!is_array($parameter)) {
            return array('status'=>0,'errmsg'=>'传入参数必须是数组');
        }
        if (!isset($parameter['scene'])) {
            $parameter['scene'] = '';
        }elseif (is_string($parameter['scene'])) {
            
        }elseif(is_array($parameter['scene'])){
            $parameter['scene'] = json_encode($parameter['scene']);
        }else{
            $parameter['scene'] = '';
        }
        
        if (!isset($parameter['page']) || empty($parameter['page'])) {
            return array('status'=>0,'errmsg'=>'缺少必要参数page');
        }
        if (!isset($parameter['width']) || empty($parameter['width'])) {
            $parameter['width'] = $this->width;
        }
        if (!isset($parameter['auto_color']) || empty($parameter['auto_color'])) {
            $parameter['auto_color'] = false;
        }
        if (!isset($parameter['line_color']) || empty($parameter['line_color']) || !is_array($parameter['line_color'])) {
            $parameter['line_color'] = $this->arrayToObject($this->line_color);
        }
        if (!isset($parameter['is_hyaline']) || empty($parameter['is_hyaline'])) {
            $parameter['is_hyaline'] = false;
        }
        
        
        $path = array(
            'scene'=>$parameter['scene'],  //此参数不能使用json字符串，因为双引号是不支持的特殊符号
            'page'=>$parameter['page'],
            'width'=>$parameter['width'],
            'auto_color'=>$parameter['auto_color'],
            'line_color'=>$parameter['line_color'],   #@此参数要的是对象
            'is_hyaline'=>$parameter['is_hyaline'],
        );
        // echo '<pre>';
        // var_dump($path);
        // die;
        $data = json_encode($path);
        $imgname = $userid.'.png';  #@图片名称
        $imgname1 = $userid.'.png';  #@图片名称
        
        if (!is_file($imgPath1 . $imgname)) { //创建图片
            set_time_limit(0);
            @ini_set('memory_limit', '256M');
            
            
            $access_token = $this->AccessToken();
            
            $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.$access_token;
            // $path="pages/mine/mine/mine?query=1";
            // $data='{"path":"'.$path.'","width":'.$this->width.'}';
            // ppp($url);
            $return = $this->request_post($url,$data);
            // ppp($return);
            
            
            $return_decode = json_decode($return,true);
            //var_dump($return_decode);
            if (isset($return_decode['errcode'])) {
                // return array('status'=>0,'errcode'=>$return_decode['errcode'],'errmsg'=>$return_decode['errmsg']);
                $errcodeMsg = isset($this->error[$return_decode['errcode']])?$this->error[$return_decode['errcode']]:'';
                return array('status'=>0,'errcode'=>$return_decode['errcode'],'errmsg'=>$return_decode['errmsg'],'msg'=>$errcodeMsg);
            }else{
                unlink($imgPath1.$imgname);
                //将生成的小程序码存入相应文件夹下
                file_put_contents($imgPath1.$imgname,$return);
                $this->pngthumb($imgPath1.$imgname, $imgPath1.$imgname1, $parameter['width'], $parameter['width']);
            } 
        }
        
        // 报错信息
        //{"errcode":47001,"errmsg":"data format error hint: [bApcla09642159]"}
        
        return array('status'=>1,'qrcodeurl'=>$imgPath.$imgname);
    }
    
    function pngthumb($sourePic,$smallFileName,$width,$heigh){
        $image=imagecreatefrompng($sourePic);//PNG
        imagesavealpha($image,true);//这里很重要 意思是不要丢了$sourePic图像的透明色;
        $BigWidth=imagesx($image);//大图宽度
        $BigHeigh=imagesy($image);//大图高度
        $thumb = imagecreatetruecolor($width,$heigh);
        imagealphablending($thumb,false);//这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;
        imagesavealpha($thumb,true);//这里很重要,意思是不要丢了$thumb图像的透明色;
        if(imagecopyresampled($thumb,$image,0,0,0,0,$width,$heigh,$BigWidth,$BigHeigh)){
        imagepng($thumb,$smallFileName);
        }
        return $smallFileName;//返回小图路径 转载注明 www.chhua.com
    }


    #C接口，生成二维码，可接受path参数较长，生成个数受限【方形码】。
    /*
     三、获取小程序二维码的方式三【方形码】
     适用场景：适用于需要的码数量较少的业务场景
     接口地址：https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN
     注    意：通过该接口生成的小程序二维码，永久有效，数量限制见文末说明，请谨慎使用。
     用户扫描该码进入小程序后，将直接进入 path 对应的页面。
     示    例：
     {"path": "pages/index?query=1", "width": 430}
     注：pages/index 需要在 app.json 的 pages 中定义
     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     传输方式：  POST
     参数    类型    默认值      说明
     path    String              不能为空，最大长度 128 字节
     width   Int     430         二维码的宽度
     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    
    
    /**
     * [getwxaqrcode 获取菊花码方式一 不带用户自定义参数]
     * @param  [type] $parameter [数组
     *$parameter = array(
     *      'path'=>[string],
     *      'width'=>[int],
     *);
     *
     * @return [type]       [description]
     */
    public function getwxaqrcode_c($parameter)
    {
        // 存储路径
        $imgPath = $this->imgPath.'C/';
        if (!is_dir($imgPath)) {
            mkdir($imgPath);
        }
        
        if (!is_array($parameter)) {
            return array('status'=>0,'errmsg'=>'传入参数必须是数组');
        }
        
        if (!isset($parameter['path']) || empty($parameter['path'])) {
            return array('status'=>0,'errmsg'=>'缺少必要参数path');
        }
        if (!isset($parameter['width']) || empty($parameter['width'])) {
            $parameter['width'] = $this->width;
        }
        
        
        $path = array(
            'path'=>$parameter['path'],
            'width'=>$parameter['width'],
        );
        // echo '<pre>';
        // var_dump($path);
        // die;
        $data = json_encode($path);
        $imgname = md5($data).'.png';  #@图片名称 图片永久有效
        
        if (!is_file($imgPath . $imgname)) { //创建图片
            set_time_limit(0);
            @ini_set('memory_limit', '256M');
            
            
            $access_token = $this->AccessToken();
            
            $url = 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token='.$access_token;
            $return = $this->request_post($url,$data);
            
            $return_decode = json_decode($return,true);
            if (isset($return_decode['errcode'])) {
                // return array('status'=>0,'errcode'=>$return_decode['errcode'],'errmsg'=>$return_decode['errmsg']);
                $errcodeMsg = isset($this->error[$return_decode['errcode']])?$this->error[$return_decode['errcode']]:'';
                return array('status'=>0,'errcode'=>$return_decode['errcode'],'errmsg'=>$return_decode['errmsg'],'msg'=>$errcodeMsg);
            }else{
                
                //将生成的小程序码存入相应文件夹下
                file_put_contents($imgPath.$imgname,$return);
                
            }
            
            
        }
        
        // 报错信息
        //{"errcode":47001,"errmsg":"data format error hint: [bApcla09642159]"}
        
        // return array(1,$this->imgurl.'C/'.$imgname);
        return array('status'=>1,'qrcodeurl'=>$this->imgurl.'C/'.$imgname);
    }
    
    public function AccessToken()
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->appsecret;
        $AccessToken = $this->request_post($url);
        $AccessToken = json_decode($AccessToken , true);
        $AccessToken = $AccessToken['access_token'];
        return $AccessToken;
    }
    public function request_post($url, $data=''){
        $ch = curl_init();
        $header = ["Accept-Charset: utf-8"];
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $tmpInfo = curl_exec($ch);
        if (curl_errno($ch)) {
            return false;
        }else{
            return $tmpInfo;
        }
    }
    public function arrayToObject($e){
        
        if( gettype($e)!='array' ) return;
        foreach($e as $k=>$v){
            if( gettype($v)=='array' || getType($v)=='object' )
                $e[$k]=(object)arrayToObject($v);
        }
        return (object)$e;
    }
    
    public function objectToArray($e){
        $e=(array)$e;
        foreach($e as $k=>$v){
            if( gettype($v)=='resource' ) return;
            if( gettype($v)=='object' || gettype($v)=='array' )
                $e[$k]=(array)objectToArray($v);
        }
        return $e;
    }
}